/*
 * utils.c
 *
 * Common helper utilities.
 *
 * Copyright (C) 2021 Rinnegatamante
 * Copyright (C) 2022 Volodymyr Atamanenko
 *
 * This software may be modified and distributed under the terms
 * of the MIT license. See the LICENSE file for details.
 */

#include <psp2/io/stat.h>

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>

#include "utils.h"

// For check_kubridge
SceUID _vshKernelSearchModuleByName(const char *, int *);

void *retNULL(void)
{
    return NULL;
}

int ret0(void)
{
    return 0;
}

int ret1(void)
{
    return 1;
}

int retminus1(void)
{
    return -1;
}

void do_nothing(void)
{
    // Silence is golden.
}

void trimString(char *str)
{
	int len = strlen(str);
	int i;

	for (i = len - 1; i >= 0; i--)
	{
		if (str[i] == ' ')
			str[i] = 0;
		else
			break;
	}
}

int file_exists(const char *path)
{
    SceIoStat stat;
    return sceIoGetstat(path, &stat) >= 0;
}

int ReadFile(const char *file, void *buf, int size)
{
    SceUID fd = sceIoOpen(file, SCE_O_RDONLY, 0);
    if (fd < 0)
        return fd;

    int read = sceIoRead(fd, buf, size);

    sceIoClose(fd);
    return read;
}

int WriteFile(const char *file, const void *buf, int size)
{
    SceUID fd = sceIoOpen(file, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777);
    if (fd < 0)
        return fd;

    int written = sceIoWrite(fd, buf, size);

    sceIoClose(fd);
    return written;
}

int allocateReadFile(const char *file, void **buffer)
{
    SceUID fd = sceIoOpen(file, SCE_O_RDONLY, 0);
    if (fd < 0)
        return fd;

    int size = sceIoLseek32(fd, 0, SCE_SEEK_END);
    sceIoLseek32(fd, 0, SCE_SEEK_SET);

    *buffer = malloc(size);
    if (!*buffer)
    {
        sceIoClose(fd);
        return -1;
    }

    uint8_t *buf = (uint8_t *)*buffer;
    int read_size = 0;

    while (1)
    {
        int read = sceIoRead(fd, buf, TRANSFER_SIZE);
        if (read < 0)
        {
            free(*buffer);
            *buffer = NULL;
            sceIoClose(fd);
            return -1;
        }

        if (read == 0)
            break;

        buf += read;
        read_size += read;
    }
    sceIoClose(fd);

    return read_size;
}

int debugPrintf(char *text, ...)
{
#ifdef DEBUG
    va_list list;
    char string[4096];

    va_start(list, text);
    vsprintf(string, text, list);
    va_end(list);
    printf("%s", string);
#ifdef DEBUG_FILE
    SceUID fd = sceIoOpen(LOG_PATH, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_APPEND, 0777);
    if (fd >= 0)
    {
        sceIoWrite(fd, string, strlen(string));
        sceIoClose(fd);
    }
#endif
#endif

    return 0;
}

int check_kubridge(void)
{
    int search_unk[2];
    return _vshKernelSearchModuleByName("kubridge", search_unk);
}
